#!/bin/sh
#
# Creates PHP release packages.
#
# Written by Stig Bakken <ssb@guardian.no> 1997-05-28.
# Adapted to Git by Stanislav Malyshev <stas@php.net>.

# Check whether gtar is present (GNU tar)
tar="$(which gtar)"
tar="${tar:-$(which tar)}"

# Handle GNU vs. BSD checksum utilities
md5sum="$(which md5sum)"
md5sum="${md5sum:-$(which md5)}"

# GNU touch is preferred since it handles local TZ in timestamps
touch="$(which gtouch)"
touch="${touch:-$(which touch)}"

if [[ $($tar --version) == *"bsdtar"* ]]; then
  echo "Found bsdtar at $tar, but this script needs GNU tar."
  exit 1
fi

# Go to project root directory.
cd "$(CDPATH='' cd -- "$(dirname -- "$0")/../../" && pwd -P)" || exit

# Process options and arguments.
while :; do
  case $1 in
    -h|--help)
      cat << HELP
PHP distribution generator

Creates PHP release packages (tar.gz, tar.bz2, tar.xz) from the php-src Git
repository. The snapshot archive includes also generated configure script,
configuration headers, parsers, lexers, and similar generated files to simplify
the installation on the *nix systems.

SYNOPSIS:
  makedist [options] <tree-ish>

OPTIONS:
  -h, --help        Display this help.
  --remote=<repo>   Instead of using a local repository, retrieve a tar archive
                    from a remote repository.
  <tree-ish>        The Git tree or Git commit to produce an archive for. This
                    script needs a consistent tagging of releases. Each release
                    of a package should have a tag of the form:
                      php-X.Y.Z[alpha|beta|RC]

                    or branch:
                       PHP-X.Y[.Z]

                    Where:
                      - X is major version number
                      - Y is minor version number
                      - Z is patch version number
                      - last part of tag is optional and is one of RC, alpha, or
                        beta and belonging number.

EXAMPLES:

  Create snapshot of the master branch:
    scripts/dev/makedist

  Create snapshot of the PHP-7.4 branch:
    scripts/dev/makedist PHP-7.4

  Create release packages for the stable tag php-7.4.0:
    scripts/dev/makedist php-7.4.0

  Create release candidate packages for the tag php-7.4.0RC1:
    scripts/dev/makedist php-7.4.0RC1

  Create release packages from a remote Git repository for the tag php-7.4.0:
    scripts/dev/makedist --remote=git@github.com:php/php-src.git php-7.4.0
HELP
      exit
      ;;
    --remote)
      # Check for an option argument.
      if test -n "$2"; then
        remote=$2
        shift
      else
        echo "makedist: '--remote' requires a non-empty option argument." >&2
        exit 1
      fi
      ;;
    --remote=?*)
      # Set everything after the "=".
      remote=${1#*=}
      ;;
    --remote=)
      # When passing empty "--remote=" option.
      echo "makedist: '--remote' requires a non-empty option argument." >&2
      exit 1
      ;;
    -?*)
      echo "makedist WARNING: Unknown option (ignored): '$1'" >&2
      ;;
    *)
      # When no more options, check for an argument and break out of the loop.
      if test -n "$1"; then
        treeish="$1"
        prefix="$treeish"
      elif test -z "$treeish"; then
        treeish="master"
        prefix="php-master-"$(date +"%Y-%m-%d-%H-%M")
      fi
      break
  esac

  shift
done

# Verify that the temporary directory for the package files doesn't exist.
if test -d "$prefix"; then
  echo "makedist: The directory $prefix" >&2
  echo "          already exists. Rename or remove it and run makedist again." >&2
  exit 1
fi

if test -n "$remote"; then
  remote_option="--remote=$remote"
  git=$remote
else
  echo "makedist: Verifying that tree-ish $treeish exists in Git repository."
  git rev-parse --verify $treeish
  exit_code=$?
  if test "$exit_code" != "0"; then
    echo "makedist: $treeish is not found in the Git repository." >&2
    exit $exit_code
  else
    echo "makedist: OK"
  fi

  git="current Git repository."
fi

# Export PHP.
echo "makedist: Exporting $treeish from $git"
git archive --format=tar $remote_option --prefix=$prefix/ $treeish | "$tar" xvf - || exit 4

cd $prefix || exit 5

# Generate configure script so autoconf is not required to install.
echo ""
echo "makedist: Generating files."
./buildconf --force

# Generate lexer and parser files so bison and re2c aren't required to install.
./scripts/dev/genfiles
exit_code=$?
if test "$exit_code" != "0"; then
  exit $exit_code
fi

# Remove not needed files.
rm -rf autom4te.cache/

# Download PEAR.
echo ""
echo "makedist: Attempting to download PEAR's phar archive."
if test ! -x wget; then
  wget https://pear.php.net/install-pear-nozlib.phar -nd -P pear/
  if [ "x$?" != "x0" ]; then
    echo "makedist: PEAR download failed." >&2
    exit 1
  fi
else
  echo "makedist: Missing wget binary needed for PEAR download." >&2
  exit 1
fi

# Reset the modification and access times of all files to be packaged.
commitDate="$(git log -1 --format=%cI $treeish)"
echo "makedist: Resetting the modification and access times of package files to $commitDate"
"$touch" -c -d"$commitDate" NEWS
find . -exec "$touch" -r NEWS -c {} \;

cd ..

echo ""
echo "makedist: Creating $prefix.tar archive."
"$tar" cf "$prefix".tar --owner=0 --group=0 --numeric-owner --sort=name "$prefix"
rm -rf "$prefix" "$prefix".tar.*

echo "makedist: Creating $prefix.tar.gz archive."
gzip -9 -k "$prefix".tar || exit 6
"$md5sum" "$prefix".tar.gz
gzip -t "$prefix".tar.gz

sync
sleep 2

echo "makedist: Creating $prefix.tar.bz2 archive."
bzip2 -9 -k $prefix.tar || exit 7
"$md5sum" $prefix.tar.bz2
bzip2 -t $prefix.tar.bz2

sync
sleep 2

echo "makedist: Creating $prefix.tar.xz archive."
xz -9 -k "$prefix".tar || exit 9
"$md5sum" "$prefix".tar.xz
xz -t "$prefix".tar.xz

echo ""
echo "makedist: Cleaning up."
rm -f "$prefix".tar || exit 13
echo ""
echo "makedist: All done."
